#include "myscene.h"
#include "ui_myscene.h"

#include "util/env.h"
#include "util/utility.h"
#include "util/logger.h"
#include "Geo/utility/filereader.h"
#include "Geo/utility/geo_math.h"
#include "Dialog/aboutdialog.h"
#include "Dialog/newmapdialog.h"

#include <QDebug>
#include <QFileDialog>
#include <QHBoxLayout>
#include <QIcon>
#include <QLabel>
#include <QMessageBox>
#include <QMetaType>
#include <QPushButton>
#include <QStatusBar>
#include <QString>
#include <QVBoxLayout>
#include <QHBoxLayout>

#include <QSplitter>
#include <QColorDialog>

MyScene::MyScene(QWidget *parent)
    : QMainWindow(parent),map(Env::map)
    , ui(new Ui::MyScene)
{
    ui->setupUi(this);

    iniAction();
    iniStatusBar();
    iniToolBar();
    iniMainWindow();
    connect(propertyTable->verticalHeader(),&QHeaderView::sectionClicked,
            this,&MyScene::onSelectRows);

}

MyScene::~MyScene()
{
    if (map)
        delete map;


    LInfo("Program exit");

    delete ui;
}

void MyScene::setUnit(CoordUint unitIn)
{
    switch (unitIn)
    {
    case kDegree:
        labelUnit->setText("Degree");
        break;
    case kMeter:
        break;
    case kKiloMeter:
        break;
    default:
        break;
    }

    unit = unitIn;
}
void MyScene::iniCatalog()
{
    dockCatalog=new QDockWidget();
    QWidget *catalogContent=new QWidget();
    dockCatalog->setFeatures(QDockWidget::AllDockWidgetFeatures);

    //catalog->setFeatures(QDockWidget::DockWidgetVerticalTitleBar);
    dockCatalog->setWindowTitle(QObject::tr("Catalog"));
    QComboBox *cmbCatalogKinds=new QComboBox();
    cmbCatalogKinds->addItem(QObject::tr("Computer"));
    cmbCatalogKinds->addItem(QObject::tr("Data Base"));
    QVBoxLayout *layoutCatalogContent=new QVBoxLayout();
    QStackedLayout *layoutTreeView=new QStackedLayout();

    FileTreeView *fileTreeView=new FileTreeView();
    DBTreeWidget *dbTreeWidget=new DBTreeWidget();
    layoutTreeView->insertWidget(0,fileTreeView);

    layoutTreeView->insertWidget(1,dbTreeWidget);
    layoutCatalogContent->addWidget(cmbCatalogKinds);
    layoutCatalogContent->addLayout(layoutTreeView);
    catalogContent->setLayout(layoutCatalogContent);
    dockCatalog->setWidget(catalogContent);

    connect(cmbCatalogKinds, QOverload<int>::of(&QComboBox::activated),
                  layoutTreeView, &QStackedLayout::setCurrentIndex);

}

void MyScene::showMsg(const QString &msg, int timeMs)
{
    ui->statusbar->showMessage(msg, timeMs);
}

void MyScene::iniStatusBar()
{
    labelCoord = new QLabel();
    labelUnit = new QLabel();
    ui->statusbar->addWidget(labelCoord);
    ui->statusbar->addWidget(labelUnit);
    onUpdateCoord(0.0, 0.0);
}

void MyScene::iniToolBar()
{
    
    toolbarMouseCursor=new QToolBar(this);
    toolbarMouseCursor->addAction(actCursorPalm);
    toolbarMouseCursor->addAction(actCursorNormal);
    toolbarMouseCursor->addAction(actCursorEditing);
    toolbarMouseCursor->addAction(actCursorWhatIsThis);


    toolbarEditLayer=new QToolBar(this);
    comboCurLayer=new QComboBox();
    comboCurEditStatus=new QComboBox();
    toolbarEditLayer->addAction(actOpenShapfile);
    toolbarEditLayer->addAction(actStatisticField);
    toolbarEditLayer->addAction(actSetting);
    toolbarEditLayer->addAction(rotateAction);
    toolbarEditLayer->addWidget(editRotate);
    toolbarEditLayer->addWidget(comboCurLayer);



    this->addToolBar(toolbarMouseCursor);
    this->addToolBar(toolbarEditLayer);

    connect(AppEvent::getInstance(), &AppEvent::sigStartEditing,
        this, &MyScene::onStartEditing);
    connect(this, &MyScene::sigUpdateOpengl,
        AppEvent::getInstance(), &AppEvent::onUpdateOpengl);
    connect(AppEvent::getInstance(), &AppEvent::sigUpdateCoord,
        this, &MyScene::onUpdateCoord);
    connect(AppEvent::getInstance(), &AppEvent::sigUpdateProTable,
        this, &MyScene::onUpdateProTable);
    //set dark/light theme signal-slot link
    connect(AppEvent::getInstance(),&AppEvent::sigSetDarkTheme,
            this,&MyScene::onSetDarkTheme);
    connect(AppEvent::getInstance(),&AppEvent::sigSetLightTheme,
            this,&MyScene::onSetLightTheme);
    //set add/delete field signal-slot link
    connect(AppEvent::getInstance(),&AppEvent::sigAddField,
            this,&MyScene::onAddField);
    connect(AppEvent::getInstance(),&AppEvent::sigDeleteField,
            this,&MyScene::onDeleteField);
}

void MyScene::onUpdateCoord(double x, double y)
{
    switch (unit)
    {
    case kDegree:
    {

        QString coordText = QString("%1E %2N").arg(x, 8, 'f', 5).arg(y, 8, 'f', 5);
        labelCoord->setText(coordText);
        break;
    }
    case kMeter:
        break;
    case kKiloMeter:
        break;
    default:
        break;
    }
}

void MyScene::onUpdateProTable(GeoLayer* layer)
{
    if (layer&&layer->getLayerType() == kFeatureLayer)
    {
        GeoFeatureLayer* layerIn = layer->toFeatureLayer();
        readProTableFeatureLayer(layerIn);
    }
}

void MyScene::readProTableFeatureLayer(GeoFeatureLayer* layer)
{
    if (!layer || layer->isEmpty())
    {
        return;
    }
    QString layerName=layer->getName();
    tabWidget->setTabText(0,layerName);
    int featuresCount = layer->getFeatureCount();
    int fieldsCount = layer->getNumFields();

    propertyTable->clear();
    propertyTable->setColumnCount(fieldsCount + 1);

    propertyTable->setRowCount(featuresCount + 1);
    propertyTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
    propertyTable->horizontalHeader()->setStyleSheet(
        "QHeaderView::section{background::rgb(0,122,204);}"
    );
    QStringList header;
    header << "FID";
    for (int i = 0; i < fieldsCount; ++i)
    {
        header << layer->getFieldDefn(i)->getName();
    }
    propertyTable->setHorizontalHeaderLabels(header);

    for (int iFeature = 0; iFeature < featuresCount; ++iFeature)
    {
        //qDebug()<<"read"<<iFeature<<"row";
        GeoFeature *feature = layer->getFeature(iFeature);
        if (!feature || feature->isDeleted())
        {
            continue;
        }

        QTableWidgetItem* item = new QTableWidgetItem();
        item->setTextAlignment(Qt::AlignRight);
        item->setText(QString::number(feature->getFID()));
        propertyTable->setItem(iFeature, 0, item);
        for (int iCol = 0; iCol < fieldsCount; ++iCol)
        {
            //qDebug()<<"read"<<iCol<<"Column";
            QTableWidgetItem* item = new QTableWidgetItem();
            GeoFieldDefn* fieldDefn = layer->getFieldDefn(iCol);
            switch (fieldDefn->getType())
            {
            default:
                break;
            case kFieldInt:
            {
                item->setTextAlignment(Qt::AlignRight);
                int value;
                feature->getField(iCol, &value);

                item->setText(QString::number(value));
                break;
            }
            case kFieldDouble:
            {
                item->setTextAlignment(Qt::AlignRight);
                double value;
                feature->getField(iCol, &value);
                item->setText(QString::number(value));
                break;
            }
            case kFieldText:
            {
                item->setTextAlignment(Qt::AlignLeft);
                QString value;
                feature->getField(iCol, &value);
                item->setText(value);
                break;
            }
            }// end switch
            propertyTable->setItem(iFeature, iCol + 1, item);

        }// end for iCol
    }
}

/***************************************************
 *
 *      Change Mouse Cursor Type
 *          1. normal
 *          2. palm shape
 *          3. editing
 *          4. What is this
 *          5. Cross
 *
 *
****************************************************/

void MyScene::onStartEditing(bool on)
{
    if (on)
    {
        Env::cursorType = Env::CursorType::Editing;
        // Editing
        actCursorEditing->setEnabled(true);
        actCursorEditing->setChecked(true);
        // Normal
        actCursorNormal->setEnabled(false);
        actCursorNormal->setChecked(false);
        // Palm
        actCursorPalm->setChecked(false);
        // What Is This
        actCursorWhatIsThis->setChecked(false);
        // rotate
        editRotate->setEnabled(true);
        rotateAction->setEnabled(true);
        propertyTable->setEditTriggers(QAbstractItemView::DoubleClicked);
    }
    else
    {
        actCursorNormal->setEnabled(true);
        actCursorEditing->setEnabled(false);
        editRotate->setEnabled(false);
        rotateAction->setEnabled(false);
        if (actCursorEditing->isChecked()) {
            Env::cursorType = Env::CursorType::Normal;
            actCursorEditing->setChecked(false);
            actCursorNormal->setChecked(true);
        }
    }
    comboCurLayer->clear();
    comboCurLayer->addItem(Env::curLayerName);


}

void MyScene::onCursorNormal()
{
    if (!actCursorNormal->isChecked()) {
        if (Env::cursorType == Env::CursorType::Normal) {
            actCursorNormal->setChecked(true);
        }
    }
    else {
        Env::cursorType = Env::CursorType::Normal;
        actCursorPalm->setChecked(false);
        actCursorEditing->setChecked(false);
        actCursorWhatIsThis->setChecked(false);
    }
}

void MyScene::onCursorEditing()
{
    if (!actCursorEditing->isChecked()) {
        if (Env::cursorType == Env::CursorType::Editing) {
            actCursorEditing->setChecked(true);
        }
    }
    else {
        Env::cursorType = Env::CursorType::Editing;
        actCursorNormal->setChecked(false);
        actCursorPalm->setChecked(false);
        actCursorWhatIsThis->setChecked(false);
    }
}

void MyScene::onCursorPalm()
{
    if (!actCursorPalm->isChecked()) {
        if (Env::cursorType == Env::CursorType::Palm) {
            actCursorWhatIsThis->setChecked(true);
        }
    }
    else {
        Env::cursorType = Env::CursorType::Palm;
        actCursorNormal->setChecked(false);
        actCursorEditing->setChecked(false);
        actCursorWhatIsThis->setChecked(false);
    }
}

void MyScene::onCursorWhatIsThis()
{
    if (!actCursorWhatIsThis->isChecked()) {
        if (Env::cursorType == Env::CursorType::WhatIsThis) {
            actCursorWhatIsThis->setChecked(true);
        }
    }
    else {
        Env::cursorType = Env::CursorType::WhatIsThis;
        actCursorNormal->setChecked(false);
        actCursorPalm->setChecked(false);
        actCursorEditing->setChecked(false);
    }
}

void MyScene::onRotate() {
    if (editRotate->text().isEmpty())
        return;
    double angle = editRotate->text().toDouble();
    std::map<GeoFeatureLayer*, std::vector<GeoFeature*>> selectedFeatures;
    map->getAllSelectedFeatures(selectedFeatures);
    Env::opList.addRotateOperation(selectedFeatures, angle)->operate();
    emit sigUpdateOpengl();
}

void MyScene::iniMainWindow()
{
    this->setFocusPolicy(Qt::StrongFocus);
    this->setWindowTitle(tr("MyScene"));
    this->setWindowIcon(QIcon("../Resources/icons/icon_NO1.ico"));
    qRegisterMetaType<GeoFeature>("GeoFeature&");
    qRegisterMetaType<GeoLayer>("GeoLayer");
    qRegisterMetaType<GeoFeatureLayer>("GeoFeatureLayer");
    qRegisterMetaType<GeoRasterLayer>("GeoRasterLayer");

    QString logFilePath = QDir::currentPath() + "/logs";
    QDir dir(logFilePath);
    if (!dir.exists())
    {
        dir.mkdir(logFilePath);
    }

    LInfo("Program start");
    Env::map->setName("untitled");

    iniMenuBar();
    iniWidget();

    //iniPanle();
}

void MyScene::iniAction()
{

    editRotate = new QLineEdit(this);
    editRotate->setFixedWidth(60);
    editRotate->setAlignment(Qt::AlignRight);
    // [-360.00, 360.00]
    QRegExp re("^-?(360|[1-2]?\\d?\\d|[1-3]?[0-5]?\\d(\\.\\d{1,2})?)$");
    editRotate->setValidator(new QRegExpValidator(re, editRotate));
    editRotate->setDisabled(true);
    connect(editRotate, &QLineEdit::returnPressed, this, &MyScene::onRotate);

    // cursor type
    // palm
    actCursorPalm = new QAction(this);
    actCursorPalm->setIcon(QIcon("../Resources/color/64x64/32.png"));
    actCursorPalm->setCheckable(true);
    connect(actCursorPalm, &QAction::triggered, this, &MyScene::onCursorPalm);
    // normal
    actCursorNormal = new QAction(this);
    actCursorNormal->setCheckable(true);
    actCursorNormal->setChecked(true);
    actCursorNormal->setIcon(QIcon("../Resources/color/64x64/29.png"));
    connect(actCursorNormal, &QAction::triggered, this, &MyScene::onCursorNormal);

    // editing
    actCursorEditing = new QAction(this);
    actCursorEditing->setCheckable(true);
    actCursorEditing->setChecked(false);
    actCursorEditing->setIcon(QIcon("../Resources/color/64x64/28.png"));
    connect(actCursorEditing, &QAction::triggered, this, &MyScene::onCursorEditing);
    // what is this
    actCursorWhatIsThis = new QAction(this);
    actCursorWhatIsThis->setIcon(QIcon("../Resources/color/64x64/35.png"));
    actCursorWhatIsThis->setCheckable(true);
    connect(actCursorWhatIsThis, &QAction::triggered, this, &MyScene::onCursorWhatIsThis);

    // rotate
    rotateAction = new QAction(this);
    rotateAction->setIcon(QIcon("../Resources/color/64x64/36.png"));
    rotateAction->setDisabled(true);
    connect(rotateAction, &QAction::triggered,
            this, &MyScene::onRotate);

    //file Menu action===================================================================
    actOpenShapfile = new QAction(this);
    actOpenShapfile->setIcon(QIcon("../Resources/color/64x64/01.png"));
    actOpenShapfile->setToolTip(tr("open shpfile..."));
    actOpenShapfile->setText(tr("open shpfile"));
    connect(actOpenShapfile, &QAction::triggered,
            this, &MyScene::onOpenGeoShapefile);

    actOpenTiff = new QAction(this);
    actOpenTiff->setText(tr("open tiff"));
    connect(actOpenTiff, &QAction::triggered,
            this, &MyScene::onOpenTiff);

    actNewMap = new QAction(this);
    actNewMap->setText(tr("new map"));
    connect(actNewMap, &QAction::triggered,
            this, &MyScene::onNewMap);

    actNewLayer = new QAction(this);
    actNewLayer->setText(tr("new layer"));
    actConnectMySQL=new QAction(this);
    actConnectMySQL->setText(tr("MySQL"));
    actStatisticField=new QAction(this);
    actStatisticField->setIcon(QIcon("../Resources/color/64x64/22.png"));
    actStatisticField->setText(tr("Static Field"));
    connect(actStatisticField,&QAction::triggered,
            this,&MyScene::on_actStatisticField_triggered);
    //Tools menu action
    actSetting=new QAction(this);
    actSetting->setText(tr("Setting"));
    actSetting->setIcon(QIcon("../Resources/icons2/Edit_Option.png"));
    connect(actSetting,&QAction::triggered,
            this,&MyScene::on_actSetting_triggered);

    //Draw menu action
    actDrawPoint=new QAction(this);
    actDrawPoint->setText(tr("Draw Point"));
    actDrawPoint->setIcon(QIcon("../Resources/icons2/Painbrush.png"));
    connect(actDrawPoint,&QAction::triggered,
            this,&MyScene::on_actDrawPoint_triggered);

    actDrawLineString=new QAction(this);
    actDrawLineString->setText(tr("Draw LineString"));
    actDrawLineString->setIcon(QIcon("../Resources/icons2/Line.png"));
    connect(actDrawLineString,&QAction::triggered,
            this,&MyScene::on_actDrawLineString_triggered);

    actDrawPolygon=new QAction(this);
    actDrawPolygon->setText(tr("Draw Polygon"));
    actDrawPolygon->setIcon(QIcon("../Resources/icons2/Rectangle.png"));
    connect(actDrawPolygon,&QAction::triggered,
            this,&MyScene::on_actDrawPolygon_triggered);
    //help menu action
    actShowLog = new QAction(this);
    actShowLog->setText(tr("show log"));
    //actShowLog->setCheckable(true);
    connect(actShowLog, &QAction::triggered,
            this, &MyScene::onShowLogDialog);

    actAbout = new QAction(this);
    //actAbout->setCheckable(true);
    actAbout->setText(tr("about"));
    connect(actAbout, &QAction::triggered,
            this, &MyScene::onAbout);

    actExportCSV=new QAction(this);
    actExportCSV->setIcon(QIcon("../Resources/table.png"));
    actExportCSV->setText(tr("Export CSV"));
    connect(actExportCSV, &QAction::triggered,
            this, &MyScene::on_actExportCSV_triggered);
    actExportTXT=new QAction(this);
    actExportTXT->setIcon(QIcon("../Resources/table.png"));
    actExportTXT->setText(tr("Export TXT"));
    connect(actExportTXT, &QAction::triggered,
            this, &MyScene::on_actExportTXT_triggered);
    actExportExcel=new QAction(this);
    actExportExcel->setIcon(QIcon("../Resources/table.png"));
    actExportExcel->setText(tr("Export Excel"));
    connect(actExportExcel, &QAction::triggered,
            this, &MyScene::on_actExportExcel_triggered);

    actAddField=new QAction(this);
    actAddField->setIcon(QIcon("../Resources/add.png"));
    actAddField->setText(tr("Add Field"));
    connect(actAddField, &QAction::triggered,
            this, &MyScene::on_actAddField_triggered);
    actDeleteField=new QAction(this);
    actDeleteField->setIcon(QIcon("../Resources/close2.png"));
    actDeleteField->setText(tr("Delete Field"));
    connect(actDeleteField, &QAction::triggered,
            this, &MyScene::on_actDeleteField_triggered);
}

void MyScene::iniMenuBar()
{
    // File
    fileMenu=new QMenu(this);
    fileMenu=menuBar()->addMenu(tr("File"));
    openFileMenu=new QMenu(this);
    openFileMenu=fileMenu->addMenu(tr("Open File"));
    openFileMenu->setIcon(QIcon("../Resources/icons/open.ico"));
    openFileMenu->addAction(actOpenShapfile);
    openFileMenu->addAction(actOpenTiff);
    newFileMenu=new QMenu(this);
    newFileMenu=fileMenu->addMenu(tr("New File"));
    newFileMenu->addAction(actNewMap);
    newFileMenu->addAction(actNewLayer);
    newFileMenu->setIcon(QIcon("../Resources/icons/open.ico"));
    connectDBMenu=new QMenu(this);
    connectDBMenu=fileMenu->addMenu(tr("Connect Database"));
    connectDBMenu->addAction(actConnectMySQL);
    //Edit
    editMenu=new QMenu(this);
    editMenu=menuBar()->addMenu(tr("Edit"));
    //Analyse
    analyseMenu=new QMenu(this);
    analyseMenu=menuBar()->addMenu(tr("Analyse"));
    analyseMenu->addAction(actStatisticField);
    //Tools
    toolsMenu=new QMenu(this);
    toolsMenu=menuBar()->addMenu(tr("Tools"));
    toolsMenu->addAction(actSetting);
    //Draw
    drawMenu=new QMenu(this);
    drawMenu=menuBar()->addMenu(tr("Draw"));
    drawMenu->addAction(actDrawPoint);
    drawMenu->addAction(actDrawLineString);
    drawMenu->addAction(actDrawPolygon);
    //Window
    windowMenu=new QMenu(this);
    windowMenu=menuBar()->addMenu(tr("Window"));
    //Help
    helpMenu=new QMenu(this);
    helpMenu=menuBar()->addMenu(tr("Help"));
    //helpMenu->addAction(actAbout);
    //helpMenu->addAction(actShowLog);
    //Field
    fieldMenu=new QMenu(this);
    fieldMenu=menuBar()->addMenu(tr("Field"));
    fieldMenu->addAction(actExportCSV);
    fieldMenu->addAction(actExportTXT);
    fieldMenu->addAction(actExportExcel);
    fieldMenu->addAction(actAddField);
    fieldMenu->addAction(actDeleteField);

    //pop menu
    popMenu=new QMenu(this);

}

void MyScene::iniWidget()
{
    iniCatalog();
    //dock tabwidget layout
    dockTabWidget=new QDockWidget();
    dockTabWidget->setFeatures(QDockWidget::AllDockWidgetFeatures);
    dockTabWidget->setWindowTitle(QObject::tr("Table"));
    QWidget* dockContentTabWidget=new QWidget();
    layoutTabWidget=new QHBoxLayout(dockContentTabWidget);
    tabWidget=new QTabWidget(this);
    pageProTable=new QWidget(this);
    propertyTable=new QTableWidget(this);
    propertyTable->setAlternatingRowColors(true);
    tabWidget->addTab(pageProTable,QObject::tr("table"));
    layoutPageProTable=new QHBoxLayout(pageProTable);
    layoutPageProTable->addWidget(propertyTable);
    layoutTabWidget->addWidget(tabWidget);
    dockTabWidget->setWidget(dockContentTabWidget);
    //============================================================
    //DockLayerTree layout
    dockLayerTree=new QDockWidget();
    dockLayerTree->setFeatures(QDockWidget::AllDockWidgetFeatures);
    dockLayerTree->setWindowTitle(QObject::tr("Layers"));
    QWidget* dockContentLayerTree=new QWidget();
    layoutDockLayerTree=new QHBoxLayout(dockContentLayerTree);
    layersTreeWidget = new LayersTreeWidget();

    layoutDockLayerTree->addWidget(layersTreeWidget);
    dockLayerTree->setWidget(dockContentLayerTree);
    //========================================================
    //opengl widget layout
    openGLWidget = new OpenGLWidget();
    openglWidget3D=new OpenGLWidget3D();
    layoutCentralWidget = new QHBoxLayout();
    layoutCentralWidget->setSpacing(6);   
    layoutCentralWidget->addWidget(openGLWidget);
    //layoutCentralWidget->addWidget(openglWidget3D);
    layoutCentralWidget->setContentsMargins(11, 11, 11, 11);
    layoutCentralWidget->setStretch(0, 0);
    layoutCentralWidget->setStretch(1, 3);
    ui->centralwidget->setLayout(layoutCentralWidget);
    this->setCentralWidget(ui->centralwidget);
    /* enum Qt::DockWidgetArea flags Qt::DockWidgetAreas
     * Qt::LeftDockWidgetArea
     * Qt::RightDockWidgetArea
     * Qt::TopDockWidgetArea
     * Qt::BottomDockWidgetArea
     * Qt::AllDockWidgetAreas
     * Qt::NoDockWidgetArea
     */
    this->addDockWidget(Qt::LeftDockWidgetArea,dockLayerTree);
    this->addDockWidget(Qt::RightDockWidgetArea,dockTabWidget);
    this->addDockWidget(Qt::RightDockWidgetArea,dockCatalog);
}


/*************************************************************/
/*                                                           */
/*                          SLOTs                            */
/*                                                           */
/*************************************************************/

// menu: file->new->map
void MyScene::onNewMap() {
    NewMapDialog* dialog = new NewMapDialog(this);
    dialog->setModal(true);
    dialog->show();
}


// menu: file->open->GeoJson
// Method1: Parse GeoJson file using JsonCpp library

// menu: file->open->Shapefile

void  MyScene::onOpenGeoShapefile()
{
    QStringList files = QFileDialog::getOpenFileNames(
        this, tr("Open File"), "", tr("shapefile(*.shp)"), nullptr,
        QFileDialog::DontUseNativeDialog);

    if (files.isEmpty())
        return;

    for (auto iter = files.begin(); iter != files.end(); ++iter)
    {
        GeoFeatureLayer *newFeatureLayer = FileReader::readShapefile(*iter, map);
        if (!newFeatureLayer)
        {
            QString errmsg = "Read and parse shapefile failed: " + *iter;
            QMessageBox::critical(this, "Error", errmsg, QMessageBox::Ok);
            LError(errmsg.toStdString());
            continue;
        }
        layersTreeWidget->onAddNewLayer(newFeatureLayer);
        openGLWidget->onSendFeatureLayerToGPU(newFeatureLayer, false);    // not update immediately
        //openglWidget3D->onSendFeatureLayerToGPU(newFeatureLayer, false);    // not update immediately
    }

    //searchWidget->updateCompleterList();
    openGLWidget->update();
    //openglWidget3D->update();
}

// file->open->Tiff
void  MyScene::onOpenTiff()
{
    QStringList files = QFileDialog::getOpenFileNames(
        this, tr("Open File"), "", tr("TIFF(*.tif)"), nullptr,
        QFileDialog::DontUseNativeDialog);

    if (files.isEmpty())
        return;

    for (auto iter = files.begin(); iter != files.end(); ++iter) {
        GeoRasterLayer *newRasterLayer = FileReader::readTiff(*iter, map);
        if (!newRasterLayer) {
            QString errmsg = "Read and parse TIFF image failed: " + *iter;
            QMessageBox::critical(this, "Error", errmsg, QMessageBox::Ok);
            LError(errmsg.toStdString());
            return;
        }
        layersTreeWidget->onAddNewLayer(newRasterLayer);
        openGLWidget->onSendRasterLayerToGPU(newRasterLayer, false); // not update immediately
    }

    //searchWidget->updateCompleterList();
    openGLWidget->update();
}

void  MyScene::onShowLogDialog() {
    viewLogDialog = new ViewLogDialog(this);
    viewLogDialog->setFixedSize(800, 300);
    viewLogDialog->setModal(false);
    viewLogDialog->show();
}

void MyScene::onAbout() {
    AboutDialog* aboutDialog = new AboutDialog(this);
    aboutDialog->setModal(true);
    aboutDialog->show();
}

void MyScene::on_actStatisticField_triggered()
{
    StatisticFieldDialog *statisticFieldDialog=new StatisticFieldDialog(map,this);
    statisticFieldDialog->show();
}

void MyScene::on_actSetting_triggered()
{
    SettingDialog *settingDialog=new SettingDialog(this);
    settingDialog->show();
}

void MyScene::closeEvent(QCloseEvent *event)
{
    int button = QMessageBox::question(this, "Prompt", "Save the project?",
        QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
    if (button == QMessageBox::Cancel) {
        event->ignore();
        return;
    }
    else if (button == QMessageBox::Yes) {

    }
    else
    {
        QMainWindow::closeEvent(event);
    }
}

void MyScene::on_actDrawPoint_triggered()
{
    Env::cursorType=Env::CursorType::Cross;
    Env::drawType=Env::DrawType::point; 
}
void MyScene::on_actDrawLineString_triggered()
{
    Env::cursorType=Env::CursorType::Cross;
    Env::drawType=Env::DrawType::line;
}
void MyScene::on_actDrawPolygon_triggered()
{
    Env::cursorType=Env::CursorType::Cross;
    Env::drawType=Env::DrawType::polygon;
}

void MyScene::onSetDarkTheme()
{
    QFile darkThemeFile("../Resources/themes/dark.qss");
    darkThemeFile.open(QFile::ReadOnly);
    QString darkStyleSheet= QString::fromLatin1(darkThemeFile.readAll());
    qApp->setStyleSheet(darkStyleSheet);
    propertyTable->setAlternatingRowColors(false);
    Env::renderer.setTheme("dark");
    emit sigUpdateOpengl();
}
void MyScene::onSetLightTheme()
{
    QFile darkThemeFile("../Resources/themes/light.qss");
    darkThemeFile.open(QFile::ReadOnly);
    QString darkStyleSheet= QString::fromLatin1(darkThemeFile.readAll());
    qApp->setStyleSheet(darkStyleSheet);
    propertyTable->setAlternatingRowColors(true);
    Env::renderer.setTheme("light");
    emit sigUpdateOpengl();
}

void MyScene::on_actExportCSV_triggered()
{
    QString filePath=QFileDialog::getSaveFileName(
                this,tr("Save as..."),QString(),tr("CSV file(*.csv)"),
                nullptr,QFileDialog::DontUseNativeDialog);
    qDebug()<<"fiel path:"<<filePath;
    if(filePath!="")
    {
        int row=propertyTable->rowCount();
        int col=propertyTable->columnCount();
        QList<QString> list;
        QString headerRow;
        for(int i=0;i<col;++i){
            headerRow.append(propertyTable->horizontalHeaderItem(i)->text()+",");
        }
        list.push_back(headerRow);
        for(int i=0;i<row-1;++i){
            QString rowStr="";
            for(int j=0;j<col;++j){
                rowStr+=propertyTable->item(i,j)->text()+",";
            }
            list.push_back(rowStr);
        }
        QTextEdit textEdit;
        for(int i=0;i<list.size();++i){
            textEdit.append(list.at(i));
        }
        QFile file(filePath);
        if(file.open(QFile::WriteOnly|QIODevice::Text)){
            QTextStream ts(&file);
            ts.setCodec("UTF-8");
            ts<<textEdit.document()->toPlainText();
            file.close();
        }
        QMessageBox::information(this,"Tips","Data Export CSV File Success!",QMessageBox::Ok);
    }
}
void MyScene::on_actExportTXT_triggered()
{
    QString filePath=QFileDialog::getSaveFileName(
                this,tr("Save as..."),QString(),tr("TXT file(*.txt)"),
                nullptr,QFileDialog::DontUseNativeDialog);
    if(filePath!="")
    {
        int row=propertyTable->rowCount();
        int col=propertyTable->columnCount();
        QList<QString> list;
        QString headerRow;
        for(int i=0;i<col;++i){
            headerRow.append(propertyTable->horizontalHeaderItem(i)->text()+" ");
        }
        list.push_back(headerRow);
        for(int i=0;i<row-1;++i){
            QString rowStr="";
            for(int j=0;j<col;++j){
                rowStr+=propertyTable->item(i,j)->text()+" ";
            }
            list.push_back(rowStr);
        }
        QTextEdit textEdit;
        for(int i=0;i<list.size();++i){
            textEdit.append(list.at(i));
        }
        QFile file(filePath);
        if(file.open(QFile::WriteOnly|QIODevice::Text)){
            QTextStream ts(&file);
            ts.setCodec("UTF-8");
            ts<<textEdit.document()->toPlainText();
            file.close();
        }
        QMessageBox::information(this,"Tips","Data Export TXT File Success!",QMessageBox::Ok);
    }

}

void MyScene::on_actExportExcel_triggered()
{
    QString filePath=QFileDialog::getSaveFileName(
                this,tr("Save as..."),QString(),tr("EXCEL file(*.xls)"),nullptr,
                QFileDialog::DontUseNativeDialog);

    if(filePath!="")
    {
        int row=propertyTable->rowCount();
        int col=propertyTable->columnCount();
        QList<QString> list;
        QString headerRow;
        for(int i=0;i<col;++i){
            headerRow.append(propertyTable->horizontalHeaderItem(i)->text()+"\t");
        }
        list.push_back(headerRow);
        for(int i=0;i<row-1;++i){
            QString rowStr="";
            for(int j=0;j<col;++j){
                rowStr+=propertyTable->item(i,j)->text()+"\t";
            }
            list.push_back(rowStr);
        }
        QTextEdit textEdit;
        for(int i=0;i<list.size();++i){
            textEdit.append(list.at(i));
        }
        QFile file(filePath);
        if(file.open(QFile::WriteOnly|QIODevice::Text)){
            QTextStream ts(&file);
            ts.setCodec("UTF-8");
            ts<<textEdit.document()->toPlainText();
            file.close();
        }
        QMessageBox::information(this,"Tips","Data Export EXCEL File Success!",QMessageBox::Ok);
    }
}

void MyScene::on_actAddField_triggered()
{
    AddFieldDialog *dialog=new AddFieldDialog(this);
    dialog->show();
}
void MyScene::onAddField( QString fieldName, GeoFieldType fieldType)
{
    QString layerName=tabWidget->tabText(0);
    //GeoFeatureLayer *layer=map->getLayerByName(layerName)->toFeatureLayer();

    map->getLayerByName(layerName)->toFeatureLayer()->addField(fieldName,20,fieldType);
    int colCount=propertyTable->columnCount();
    QTableWidgetItem *headerItem=new QTableWidgetItem();
    headerItem->setText(fieldName);
    propertyTable->insertColumn(colCount);
    propertyTable->setHorizontalHeaderItem(colCount,headerItem);
}

void MyScene::on_actDeleteField_triggered()
{
    QStringList headerRow;
    int colCount=propertyTable->columnCount();
    for(int i=1;i<colCount;++i){
        headerRow.append(propertyTable->horizontalHeaderItem(i)->text());
    }
    DeleteFieldDialog *dialog=new DeleteFieldDialog(headerRow,this);
    dialog->show();
}

void MyScene::onDeleteField(int fieldIndex)
{
    QString layerName=tabWidget->tabText(0);
    propertyTable->removeColumn(fieldIndex+1);
    //map->getLayerByName(layerName)->toFeatureLayer()->;
}

void MyScene::onSelectRows()
{

    auto selectedItems=propertyTable->selectedItems();
    // std::set
    // the emelem in std::set is unique
    std::set<int> rowsIndexes;
    // get all selected rows
    for (const auto& item : selectedItems) {
        rowsIndexes.insert(item->row());
    }

    std::vector<int> selectedFIDs;
    selectedFIDs.reserve(rowsIndexes.size());

    for (auto idx : rowsIndexes) {
        int nFID = propertyTable->item(idx, 0)->text().toInt();
        selectedFIDs.push_back(nFID);
    }
    QString layerName=tabWidget->tabText(0);
    map->getLayerByName(layerName)->toFeatureLayer()->setSelectedFeatures(selectedFIDs);
    emit sigUpdateOpengl();
}






